home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / slang / slutty.c < prev   
Encoding:
C/C++ Source or Header  |  1996-05-17  |  5.7 KB  |  253 lines

  1. /* slutty.c --- Unix Low level terminal (tty) functions for S-Lang */
  2. /* Copyright (c) 1992, 1995 John E. Davis
  3.  * All rights reserved.
  4.  * 
  5.  * You may distribute under the terms of either the GNU General Public
  6.  * License or the Perl Artistic License.
  7.  */
  8.  
  9. #include <config.h>
  10. #include <stdio.h>
  11. #include <signal.h>
  12. /* sequent support thanks to Kenneth Lorber <keni@oasys.dt.navy.mil> */
  13. /* SYSV (SYSV ISC R3.2 v3.0) provided by iain.lea@erlm.siemens.de */
  14.  
  15. #ifndef sequent
  16. # include <stdlib.h>
  17. #endif
  18. #include <sys/time.h>
  19. #ifndef sequent
  20. # include <unistd.h>
  21. # include <termios.h>
  22. #endif
  23.  
  24. #ifdef SYSV
  25. # ifndef CRAY
  26. #   include <sys/termio.h>
  27. #   include <sys/stream.h>
  28. #   include <sys/ptem.h>
  29. #   include <sys/tty.h>
  30. # endif
  31. #endif
  32.  
  33. #ifndef sun
  34. #include <sys/ioctl.h>
  35. #endif
  36.  
  37. #ifdef __QNX__
  38. #include <sys/select.h>
  39. #endif
  40.  
  41. #ifdef IS_AIX
  42. #include <sys/select.h>
  43. #endif
  44.  
  45. #include <sys/types.h>
  46. #include <sys/stat.h>
  47. #include <errno.h>
  48.  
  49. #include "slang.h"
  50. #include "_slang.h"
  51.  
  52. #define TTY_DESC 2
  53. int SLang_TT_Read_FD = TTY_DESC;
  54. int SLang_TT_Baud_Rate;
  55.  
  56. static int Baud_Rates[20] = 
  57. {
  58.    0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 
  59.    9600, 19200, 38400, 0, 0, 0, 0
  60. };
  61.  
  62.  
  63.  
  64. #ifdef sequent
  65. typedef struct
  66.   {
  67.       struct tchars t;
  68.       struct ltchars lt;
  69.       struct sgttyb s;
  70.   }
  71. TTY_Termio_Type;
  72. #else
  73. typedef struct termios TTY_Termio_Type;
  74. #endif
  75.  
  76. TTY_Termio_Type Old_TTY;
  77.  
  78. /* this next works on ultrix for setting termios */
  79. #ifdef TCGETS
  80. #define GET_TERMIOS(fd, x) ioctl(fd, TCGETS, x)
  81. #define SET_TERMIOS(fd, x) ioctl(fd, TCSETS, x)
  82. #else
  83. # ifdef sequent
  84. #  define X(x,m)  &(((TTY_Termio_Type *)(x))->m)
  85. #  define GET_TERMIOS(fd, x)    \
  86.         ioctl(fd, TIOCGETC, X(x,t));\
  87.     ioctl(fd, TIOCGLTC, X(x,lt));\
  88.     ioctl(fd, TIOCGETP, X(x,s))
  89. #  define SET_TERMIOS(fd, x)    \
  90.     ioctl(fd, TIOCSETC, X(x,t));\
  91.     ioctl(fd, TIOCSLTC, X(x,lt));\
  92.     ioctl(fd, TIOCSETP, X(x,s))
  93. # else
  94. #  define GET_TERMIOS(fd, x) tcgetattr(fd, x)
  95. #  define SET_TERMIOS(fd, x) tcsetattr(fd, TCSAFLUSH, x)
  96. /* #  define SET_TERMIOS(fd, x) tcsetattr(fd, TCSANOW, x) */
  97. # endif
  98. #endif
  99.  
  100. static int TTY_Inited = 0;
  101.  
  102. int SLang_init_tty (int abort_char, int no_flow_control, int opost)
  103. {
  104.    TTY_Termio_Type newtty;
  105.    
  106.    if (TTY_Inited) return 0;
  107.     
  108.    SLang_Abort_Char = abort_char;
  109.    SLang_TT_Read_FD = fileno (stdin);
  110.    GET_TERMIOS(SLang_TT_Read_FD, &Old_TTY);
  111.    GET_TERMIOS(SLang_TT_Read_FD, &newtty);
  112. #ifdef sequent
  113.    newtty.s.sg_flags &= ~(ECHO);
  114.    newtty.s.sg_flags &= ~(CRMOD);
  115.    /*   if (Flow_Control == 0) newtty.s.sg_flags &= ~IXON; */
  116.    newtty.t.t_eofc = 1;
  117.    newtty.t.t_intrc = SLang_Abort_Char;    /* ^G */
  118.    newtty.t.t_quitc = 255;
  119.    newtty.lt.t_suspc = 255;   /* to ignore ^Z */
  120.    newtty.lt.t_dsuspc = 255;    /* to ignore ^Y */
  121.    newtty.lt.t_lnextc = 255;
  122.    newtty.s.sg_flags |= CBREAK;        /* do I want cbreak or raw????? */
  123. #else
  124.    
  125.    /* get baud rate */
  126.    
  127.    newtty.c_iflag &= ~(ECHO | INLCR | ICRNL);
  128. #ifdef ISTRIP
  129.    newtty.c_iflag &= ~ISTRIP;
  130. #endif
  131.    if (opost == 0) newtty.c_oflag &= ~OPOST;
  132.  
  133.    if (SLang_TT_Baud_Rate == 0)
  134.      {
  135. /* Note:  if this generates an compiler error, simply remove 
  136.    the statement */
  137. #ifdef HAVE_CFGETOSPEED
  138.     SLang_TT_Baud_Rate = cfgetospeed (&newtty);
  139.     
  140.     
  141.     SLang_TT_Baud_Rate = ((SLang_TT_Baud_Rate > 0) && (SLang_TT_Baud_Rate < 19)
  142.                   ? Baud_Rates[SLang_TT_Baud_Rate]
  143.                   : 0);
  144. #endif
  145.      }
  146.    
  147.    if (no_flow_control) newtty.c_iflag &= ~IXON; else newtty.c_iflag |= IXON;
  148.  
  149.    newtty.c_cc[VMIN] = 1;
  150.    newtty.c_cc[VTIME] = 0;
  151.    newtty.c_cc[VEOF] = 1;
  152.    newtty.c_lflag = ISIG | NOFLSH;
  153.    newtty.c_cc[VINTR] = SLang_Abort_Char;   /* ^G */
  154.    newtty.c_cc[VQUIT] = 255;
  155.    newtty.c_cc[VSUSP] = 255;   /* to ignore ^Z */
  156. #ifdef VSWTCH
  157.    newtty.c_cc[VSWTCH] = 255;   /* to ignore who knows what */
  158. #endif
  159. #endif /*sequent*/
  160.    SET_TERMIOS(SLang_TT_Read_FD, &newtty);
  161.    TTY_Inited = 1;
  162.    return 0;
  163. }
  164.  
  165. void SLtty_set_suspend_state (int mode)
  166. {
  167.    TTY_Termio_Type newtty;
  168.    GET_TERMIOS (SLang_TT_Read_FD, &newtty);
  169. #ifdef sequent
  170.    if (mode == 0) newtty.lt.t_suspc = 255;
  171.    else newtty.lt.t_suspc = Old_TTY.lt.t_suspc;
  172. #else
  173.    if (mode == 0) newtty.c_cc[VSUSP] = 255;
  174.    else newtty.c_cc[VSUSP] = Old_TTY.c_cc[VSUSP];
  175. #endif
  176.    SET_TERMIOS (SLang_TT_Read_FD, &newtty);
  177.    if (TTY_Inited == 0) return;   
  178. }
  179.  
  180. void SLang_reset_tty (void)
  181. {
  182.    if (!TTY_Inited) return;
  183.    SET_TERMIOS(SLang_TT_Read_FD, &Old_TTY);
  184.    TTY_Inited = 0;
  185. }
  186.  
  187. #ifdef __cplusplus
  188. # define SIGNAL(a,b) signal((a), (SIG_PF)(b))
  189. #else
  190. # define SIGNAL signal
  191. #endif
  192.  
  193. static void default_sigint (int sig)
  194. {
  195.    SLKeyBoard_Quit = 1;
  196.    if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
  197.    SIGNAL (SIGINT, default_sigint);
  198. }
  199.  
  200. void SLang_set_abort_signal (void (*hand)(int))
  201. {
  202.    if (hand == NULL) hand = default_sigint;
  203.    SIGNAL (SIGINT, hand);
  204. }
  205.  
  206. #ifndef FD_SET
  207. #define FD_SET(fd, tthis) *(tthis) = 1 << fd
  208. #define FD_ZERO(tthis)    *(tthis) = 0
  209. typedef int fd_set;
  210. #endif
  211.  
  212. static fd_set Read_FD_Set;
  213.  
  214.  
  215. int SLsys_input_pending(int tsecs)
  216. {
  217.    struct timeval wait;
  218.    long usecs, secs;
  219.    int ret;
  220.  
  221.    secs = tsecs / 10;
  222.    usecs = (tsecs % 10) * 100000;
  223.    wait.tv_sec = secs;
  224.    wait.tv_usec = usecs;
  225.    
  226.    FD_ZERO(&Read_FD_Set);
  227.    FD_SET(SLang_TT_Read_FD, &Read_FD_Set);
  228.    ret = select(SLang_TT_Read_FD + 1, &Read_FD_Set, NULL, NULL, &wait);
  229.    return (ret);
  230. }
  231.  
  232.  
  233. unsigned int SLsys_getkey (void)
  234. {
  235.    int count = 10;               /* number of times to retry if read fails */
  236.    unsigned char c;
  237.    
  238.    while ((SLKeyBoard_Quit == 0)
  239.       && !SLsys_input_pending(100));
  240.    
  241.    while (count-- && !SLKeyBoard_Quit && (read(SLang_TT_Read_FD, (char *) &c, 1) < 0)) sleep(1);
  242.    
  243.    if (count <= 0)
  244.      {
  245.     return 0xFFFF;
  246.      }
  247.  
  248.    /* only way for keyboard quit to be non zero is if ^G recived and sigint processed */
  249.    if (SLKeyBoard_Quit) c = SLang_Abort_Char;
  250.    SLKeyBoard_Quit = 0;
  251.    return((unsigned int) c);
  252. }
  253.